﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Xml.Serialization;
using System.Text;

using Microsoft.Xna.Framework.Storage;

namespace Hadron
{
    [Serializable]
    public class ScoreEntry
    {
        private String m_strName;
        private int m_nScore;

        public ScoreEntry()
        {
            m_strName = "Unknown";
            m_nScore = 0;
        }

        public ScoreEntry(String p_strName, int p_nScore)
        {
            m_strName = p_strName;
            m_nScore = p_nScore;
        }

        public String Name
        {
            get { return m_strName; }
            set { m_strName = value; }
        }

        public int Score
        {
            get { return m_nScore; }
            set { m_nScore = value; }
        }
    }

    [Serializable]
    public class ScoreTable
    {
        private int m_nMaxEntries;
        private List<ScoreEntry> m_listScoreEntries;

        public ScoreTable()
        {
            m_nMaxEntries = 20;
            m_listScoreEntries = new List<ScoreEntry>();
        }

        public bool Qualifies(int p_nScore)
        {
            if (m_listScoreEntries.Count < m_nMaxEntries)
                return true;

            ScoreEntry scoreEntryLast = m_listScoreEntries.Last();
            return scoreEntryLast.Score < p_nScore;
        }

        public void Generate()
        {
            m_listScoreEntries.Clear();
            for (int nIndex = 0; nIndex < m_nMaxEntries; nIndex++)
            {
                char ch = (char) ((int) 'A' + nIndex);
                m_listScoreEntries.Add(new ScoreEntry(new String(ch, 5), 10000 - nIndex * 400));
            }
        }

        public void InsertEntry(String p_strName, int p_nScore)
        {
            if (!Qualifies(p_nScore))
                return;

            if (m_listScoreEntries.Count == 0)
            {
                m_listScoreEntries.Add(new ScoreEntry(p_strName, p_nScore));
                return;
            }

            int nEntryIndex = 0;
            while (m_listScoreEntries[nEntryIndex].Score > p_nScore)
                ++nEntryIndex;

            ScoreEntry scoreEntry = new ScoreEntry(p_strName, p_nScore);
            m_listScoreEntries.Insert(nEntryIndex, scoreEntry);

            while (m_listScoreEntries.Count > m_nMaxEntries)
                m_listScoreEntries.RemoveAt(m_listScoreEntries.Count - 1);
        }

        public void Initialise(StorageDevice p_storageDevice)
        {
            String strFilename = Path.Combine(StorageContainer.TitleLocation, "Scores.xml");
            if (File.Exists(strFilename))
                Load(p_storageDevice);
        }

        public void Save(StorageDevice p_storageDevice)
        {
            if (p_storageDevice == null)
                return;

            String strFilename = Path.Combine(StorageContainer.TitleLocation, "Scores.xml");
            FileStream fileStream = File.OpenWrite(strFilename);
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(ScoreTable));
            xmlSerializer.Serialize(fileStream, this);
            fileStream.Close();
        }

        public void Load(StorageDevice p_storageDevice)
        {
            if (p_storageDevice == null)
                return;

            String strFilename = Path.Combine(StorageContainer.TitleLocation, "Scores.xml");

            if (!File.Exists(strFilename))
            {
                Generate();
                Save(p_storageDevice);
            }

            FileStream fileStream = File.OpenRead(strFilename);
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(ScoreTable));
            ScoreTable scoreTable = (ScoreTable) xmlSerializer.Deserialize(fileStream);
            fileStream.Close();

            m_listScoreEntries = scoreTable.Entries;
        }

        public List<ScoreEntry> Entries
        {
            get { return m_listScoreEntries; }
        }
    }
}
